package org.koin.core.instance;

import org.koin.core.Koin;
import org.koin.core.definition.BeanDefinition;
import org.koin.core.definition.OnCloseCallback;

/**
 * Single instance holder
 *
 * @author Arnaud Giuliani
 */
public class SingleInstanceFactory<T> extends InstanceFactory {

    private T value = null;

    public SingleInstanceFactory(Koin koin, BeanDefinition beanDefinition) {
        super(koin, beanDefinition);
    }

    @Override
    public T get(InstanceContext context) {
        synchronized (this) {
            if (!isCreated()) {
                value = (T) create(context);
            }
        }
        if (value == null) {
            throw new IllegalStateException("Single instance created couldn't return value");
        }
        return value;
    }

    @Override
    public boolean isCreated() {
        return value != null;
    }

    @Override
    public void drop() {
        OnCloseCallback onClose = getBeanDefinition().getCallbacks().getOnClose();
        if (onClose != null) {
            onClose.invoke(value);
        }
        value = null;
    }

    @Override
    public T create(InstanceContext context) {
        if (value == null) {
            T t = (T) super.create(context);
            if (t == null) {
                throw new IllegalStateException("Single instance created couldn't return value");
            } else {
                return t;
            }
        } else {
            return value;
        }

    }
}
